home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
- * $Author: drich $
- * $Revision: 1.1 $
- * $Date: 1995/10/03 04:08:12 $
- * $Source: /proj/freeware1.0/gopher1.12/src/gopher/RCS/manager.c,v $
- * $State: Exp $
- *
- * Paul Lindner, University of Minnesota CIS.
- *
- * Copyright 1991, 1992 by the Regents of the University of Minnesota
- * see the file "Copyright" in the distribution for conditions of use.
- *********************************************************************
- * MODULE: manager.c
- * Procedures to manage the screen.
- *********************************************************************
- * Revision History:
- * $Log: manager.c,v $
- * Revision 1.1 1995/10/03 04:08:12 drich
- * gopher 1.2 check-in
- *
- * Revision 1.3 1993/01/06 21:01:40 lindner
- * Improved behaviour when executing an item by typing it's number
- * The arrow and screen are updated to reflect the item being
- * retrieved.
- *
- * Revision 1.2 1993/01/05 22:31:57 lindner
- * Fixed display problems with directory title searching.
- *
- * Revision 1.1 1992/12/10 23:32:16 lindner
- * gopher 1.1 release
- *
- * Revision 1.1 1992/12/10 06:16:51 lindner
- * Initial revision
- *
- *
- *********************************************************************/
-
- #include "gopher.h"
-
- #define MENULINE(x) (x)+3
-
- /* If any gophers to display (screen can be blank), count the number
- of pages. If there is a remainder greater than zero, add one page */
- #define PAGECALC(x,y) (y) ? (x/y) + ((x%y)>0) : 1
-
-
-
- /*
- ** Draw the title on the top
- */
-
- void
- Draw_Banner()
- {
- standout();
- CURcenterline(CursesScreen,VERSIONline, 0);
- standend();
- }
-
-
- /*
- ** Draw the status line
- */
-
- void
- Draw_Status(textline)
- char *textline;
- {
- move(LINES-1, 0);
- clrtoeol();
- mvaddstr(LINES-1, 0, "Press ");
- standout();
- addstr("?");
- standend();
-
- addstr(" for Help, ");
-
- standout();
- addstr("q");
- standend();
- addstr(" to Quit, ");
-
- standout();
- addstr("u");
- standend();
- addstr(" to go up a menu");
- clrtoeol();
-
- mvaddch(LINES-1, COLS-strlen(textline)-2, ' ');
- addstr(textline);
- }
-
-
-
- /*
- ** Man is this ugly.
- */
-
- void
- Display_Dir_Page(gopherdir, iNewLine, nNewPage, nMaxPages, iPageLen, iLastPageLen)
- GopherDirObj *gopherdir;
- int iNewLine;
- int nNewPage, nMaxPages, iPageLen, iLastPageLen;
- {
- int i, iLoop, iOffset;
- char temp[1024];
- char *c, *d;
- int m, n, type, max;
-
- /*** Clear the screen and redraw the top line **/
- clear();
- Draw_Banner();
-
- /** Draw the menu **/
- iLoop = (nNewPage == nMaxPages) && iLastPageLen ? iLastPageLen : iPageLen;
-
- for (i= 0, iOffset = (nNewPage-1) * iPageLen; i <iLoop; i++, iOffset++) {
- move(MENULINE(i+1), 6);
- printw("%d.", iOffset +1);
- if (iOffset + 1 < 10)
- addch(' ');
-
-
- type = GSgetType(GDgetEntry(gopherdir,iOffset));
- d = GSgetTitle(GDgetEntry(gopherdir,iOffset));
- max = COLS - 13;
- switch(type)
- {
- case A_DIRECTORY:
- case A_FILE:
- max--;
- break;
- case A_SOUND:
- max -= 3;
- break;
- case A_INDEX:
- max -=4;
- break;
- case A_CSO:
- case A_TN3270:
- case A_TELNET:
- case A_UNIXBIN:
- case A_MACHEX:
- max -=6;
- break;
- case A_PCBIN:
- max -=9;
- break;
- case A_GIF:
- case A_IMAGE:
- max -= 10;
- break;
-
- }
-
- if((m = strlen(d)) <= max)
- printw(" %s", d);
- else {
- /*** Cut out the middle bits **/
- if ((c = strchr(d, '/'))!=NULL && (max > (c-d))) {
- n = c - d;
- strncpy(temp, d, n);
- strcpy(temp + n, "..");
- strcat(temp, d + (m + n - max));
- printw(" %s", temp);
- } else {
- /** Trunc it.. **/
- strcpy(temp, d);
- temp[max] ='\0';
- printw(" %s..", temp);
- }
- }
-
- switch(type)
- {
- case A_DIRECTORY:
- addch('/');
- break;
- case A_CSO:
- addstr(" <CSO>");
- break;
- case A_TN3270:
- addstr(" <3270>");
- break;
- case A_TELNET:
- addstr(" <TEL>");
- break;
- case A_INDEX:
- addstr(" <?>");
- break;
- case A_SOUND:
- addstr(" <)"); /** It's supposed to look like a speaker! **/
- break;
- case A_FILE:
- addch('.');
- break;
- case A_PCBIN:
- addstr(" <PC Bin>");
- break;
- case A_UNIXBIN:
- addstr(" <Bin>");
- break;
-
- case A_IMAGE:
- case A_GIF:
- addstr(" <Picture>");
- break;
- case A_MACHEX:
- addstr(" <HQX>");
- break;
-
- }
- }
- }
-
-
- /* scline - Screen line relocator.
- * Returns the line resulting from choice */
- int
- scline( iOldGopher, iNewGopher, gophersdir)
- int iOldGopher; /* Which gopher previously displayed */
- int iNewGopher; /* New gopher to be displayed */
- GopherDirObj *gophersdir;
- {
- int iPageLen, iLastPageLen; /* Length of normal, final pages */
- int nMaxPages, nNewPage, nOldPage; /* Natural numbers */
- int iOldLine, iNewLine; /* Screen locations */
- char sPagenum[40];
- int iMaxGophers;
-
- iMaxGophers = GDgetNumitems(gophersdir);
-
- if (iNewGopher==0)
- iNewGopher = GDgetNumitems(gophersdir);
-
- if ((iNewGopher > iMaxGophers))
- iNewGopher = 1;
-
- iPageLen = LINES-6; /* Number of menu lines possible per page */
-
- nMaxPages = PAGECALC(iMaxGophers, iPageLen); /* Total number of pages */
- nOldPage = PAGECALC(iOldGopher, iPageLen);
- nNewPage = PAGECALC(iNewGopher, iPageLen);
-
- if ((nNewPage < 1) || (nNewPage > nMaxPages)) /* It won't work , make*/
- return(iOldGopher); /* no changes */
-
- iLastPageLen = iMaxGophers % iPageLen;
-
- /* Lines on last page */
-
- iOldLine = iOldGopher - ((nOldPage-1)*iPageLen);/* Old Screen location */
- iNewLine = iNewGopher - ((nNewPage-1)*iPageLen);/* New Screen location */
-
- if ((iNewLine < 0) || (iNewLine > iPageLen))
- return(iOldGopher);
-
- if (nOldPage != nNewPage) {
- Display_Dir_Page(gophersdir,
- iNewLine, nNewPage, nMaxPages, iPageLen, iLastPageLen);
- CURcenterline(CursesScreen,GDgetTitle(gophersdir), 2); /*** Draw the title ***/
- }
-
-
- sprintf(sPagenum, " Page: %d/%d", nNewPage, nMaxPages);
- Draw_Status(sPagenum);
- mvaddstr(MENULINE(iOldLine), 1, " ");
- mvaddstr(MENULINE(iNewLine), 1, "-->");
- refresh();
-
- return(iNewGopher);
- }
-
- /*
- ** This routine draws a numbered menu
- ** from a gopherdirobj
- **
- ** It returns the number that the user selected, or it returns
- ** zero if the user decided to cancel.
- **
- */
-
- int GetMenu(gd, typedchar, redisplay)
- GopherDirObj *gd; /** where the items are **/
- int *typedchar;
- boolean redisplay;
- {
- int ch; /* Input character */
- int iItem; /* Display line */
- static int iNewItem=1;
- char sLinenum[5]; /* Used when going to a specific line */
- BOOLEAN menudone = FALSE;
- int numitems;
- /** variables for searching **/
- char search1[100];
- char *search2;
- int sfound;
- int i;
-
- search1[0] = '\0'; /* search string will be remembered so init now */
-
- numitems = GDgetNumitems(gd);
- iItem = -1;
- iNewItem = GDgetCurrentItem(gd);
-
- if (redisplay == TRUE) {
- iItem = scline(iItem, iNewItem, gd);
-
- /*** Draw the title ***/
- CURcenterline(CursesScreen,GDgetTitle(gd), 2);
- move(3+iNewItem,4);
-
- /* Move to the last line that we were sitting on */
- refresh();
- } else
- iItem = GDgetCurrentItem(gd);
-
-
- while (menudone == FALSE) {
- ch = CURgetch(CursesScreen);
-
- switch(ch)
- {
- case 'j':
- case '\016':
- case KEY_DOWN:
-
- iNewItem = iItem + 1; /* Advance down the page */
- break;
-
- case 'k':
- case '\020': /*** For those emacs dudes **/
- case KEY_UP:
-
- iNewItem = iItem - 1; /* Back up */
- break;
-
-
- case '+': /** Like in elm **/
- case '>': /** Like in nn **/
- case ' ': /** Like in the pager ***/
- case KEY_NPAGE:
- /*** Go down a page ***/
- iNewItem = iItem + (LINES -6);
- if (iNewItem > numitems)
- iNewItem = numitems;
- break;
-
-
- case '-':
- case '<':
- case KEY_PPAGE:
- case 'b': /*** Like in the pager ***/
- /*** Go up a page ***/
-
- iNewItem = iItem - (LINES - 6);
- if ( iNewItem < 0 )
- iNewItem = 1;
- break;
-
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9': case '0':
-
- sLinenum[0] = (char) ch;
- sLinenum[1] = '\0';
-
- if (CUROldGetOneOption(CursesScreen, "View item number: ", sLinenum) <0) {
- scline(iItem, iNewItem, gd);
- break;
- }
-
- if (atoi(sLinenum) <= numitems)
- iNewItem = atoi(sLinenum); /* Jump */
- else {
- CURBeep(CursesScreen);
- break;
- }
-
- scline(-1, iNewItem, gd);
-
- if (iNewItem > 0 && iNewItem <= GDgetNumitems(gd)) {
- *typedchar = '\n';
- GDsetCurrentItem(gd, iNewItem);
- return(iItem);
- }
-
-
- break;
-
- case '/':
- case 'n':
- sfound = 0;
-
- if (search1[0] == '\0' && ch == 'n') {
- CursesErrorMsg("Use '/' to define a search first...");
- iItem = scline(-1,iItem, gd);
- break;
- }
-
- if (search1[0] == '\0' || ch == '/')
- if (CURGetOneOption(CursesScreen, "Search directory titles for", search1)<0) {
- iItem = scline(-1,iItem, gd);
- break;
- }
- if (strlen(search1) == 0) {
- iItem = scline(-1, iItem, gd);
- break;
- }
-
- /*
- * Start searching from next item
- */
-
- for (i=iItem; i < numitems && sfound==0; i++) {
- search2 = GSgetTitle(GDgetEntry(gd, i));
- if (strcasestr(search2, search1) != NULL ) {
- iNewItem = i+1;
- sfound = 1;
- }
- }
- /* if it wasn't found after the current line start
- from the beginning again
- */
-
- for ( i= 0 ; i < iItem && sfound==0;i++) {
- search2 = GSgetTitle(GDgetEntry(gd,i));
- if (strcasestr(search2,search1) != NULL ) {
- iNewItem = i+1;
- sfound = 1;
- }
- }
- if (sfound == 0) {
- search1[0] = '\0';
- CURBeep(CursesScreen);
- CursesErrorMsg("Search failed...");
- }
-
- if (ch != 'n')
- iItem = scline(-1, iNewItem, gd);
- break;
-
-
- case '\0':
- break;
-
- default:
- menudone = TRUE;
- if (ch == KEY_LEFT || ch == 'h' || ch == '\002')
- ch = 'u';
- if (ch == KEY_RIGHT || ch == 'l' || ch == '\006')
- ch = '\n';
- *typedchar = ch;
- GDsetCurrentItem(gd, iItem);
- return(iItem);
- }
-
- iItem = scline(iItem, iNewItem, gd);
-
- refresh();
-
- }
-
- *typedchar = ch;
-
- GDsetCurrentItem(gd, iItem);
- return(iItem);
- }
-